﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using thinger.AutomaticStoreMotionDAL.Scanner;
using thinger.AutomaticStoreMotionModels;

namespace thinger.AutomaticStoreMotionDAL.Scale
{
    public class Scale
    {
        #region 对象
        //称重对象
        private ModbusRTU _modbusRTU = new ModbusRTU() { ReceiveTimeOut = 100 };
        #endregion

        #region 连接和断开串口通信
        public OperationResult Connect(BasicParam basicParam)
        {
            Parity parity = Parity.None;
            int dataBits = 8;
            StopBits stopBits = StopBits.None;
            GetPortParam(basicParam.cobScannerParam, out parity, out dataBits, out stopBits);
            try
            {
                _modbusRTU.OpenSerialPort(basicParam.cobWeightPort, basicParam.cobWeightBaud, parity, dataBits, stopBits);
            }
            catch (Exception ex)
            {
                return new OperationResult()
                {
                    IsSuccess = false,
                    ErrorMsg = ex.Message
                };
            }

            return OperationResult.CreateSuccessResut();
        }

        public OperationResult DisConnection()
        {
            try
            {
                _modbusRTU.CloseSerialPort();
            }
            catch (Exception ex)
            {
                return new OperationResult()
                {
                    IsSuccess = false,
                    ErrorMsg = ex.Message
                };
            }
            return OperationResult.CreateSuccessResut();
        }

        private void GetPortParam(string param, out Parity parity, out int dataBits, out StopBits stopBits)
        {
            parity = Parity.None;
            dataBits = 8;
            stopBits = StopBits.None;
            if (param.Length == 3)
            {
                switch (param.Substring(0, 1))
                {
                    case "N": parity = Parity.None; break;
                    case "E": parity = Parity.Even; break;
                    case "O": parity = Parity.Odd; break;
                    default: parity = Parity.None; break;
                }
                switch (param.Substring(1, 1))
                {
                    case "8": dataBits = 8; break;
                    case "7": dataBits = 7; break;
                    default: dataBits = 8; break;
                }
                switch (param.Substring(2, 1))
                {
                    case "2": stopBits = StopBits.Two; break;
                    case "1": stopBits = StopBits.One; break;
                    default: stopBits = StopBits.None; break;
                }
            }
        }
        #endregion

        #region 获取称重结果
        public double GetWeightValue()
        {
            double weight = 0.0f;
            byte[] bytes = _modbusRTU.ReadKeepReg(1, 0, 1);
            if (bytes != null && bytes.Length == 2)
            {
                short temp = Convert.ToInt16(bytes[0] * 256 + bytes[1]);
                weight = Math.Round(ShortToDouble(temp, 0.0, 10000.0, 655, 3276), 1);
            }
            return weight;
        }

        private double ShortToDouble(short val, double actualMin, double actualMax, short digitalMin, short digitalMax)
        {
            double k = (actualMax - actualMin) / (digitalMax - digitalMin);
            return k * (val - digitalMin) + actualMin;

        }
        #endregion

    }
}
